package wpp.fxservice;

import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.log4j.Logger;

import wpp.WPPConfig;
import wpp.cfg.DataConfig;
import wpp.cfg.WPFileBean;
import wpp.exception.WPPException;
import wpp.util.IOUtil;
import javafx.concurrent.Service;
import javafx.concurrent.Task;

public class WPStopImageHunterService extends Service<Integer> {

	private static final Logger LOGGER = Logger.getLogger(WPStopImageHunterService.class);	
	private static final String WPSTOP_BASE = "http://www.wallpaperstop.com";
	private static final String WPSTOP_TMPT = "/desktop-wallpaper-index.html";
	private static final Integer WPSTOP_MAX_PAGE = 400;
	private static final Long MAX_WPP_DOWNLOAD = 100000L;
	public static final Integer[][] WP_SIZES = new Integer[][] {
		{1920, 1080},
		{1920, 1200},		
		{1680, 1050}
	};
	private static final Integer WPSTOP_SCAN_PGAES_ONCE = 1;
	
	public WPStopImageHunterService() {
		this.setExecutor(new Executor() {			
			@Override
			public void execute(Runnable command) {
				new Thread(command).start();
			}
		});
	}
	
	@Override
	protected Task<Integer> createTask() {
		return new Task<Integer>() {			
			private Integer count;			
			@Override
			protected Integer call() throws Exception {		
				count = 0;
				doHunt(1);
				for(int i = 0; i < WPSTOP_SCAN_PGAES_ONCE; i ++) {
					doHunt(RandomUtils.nextInt(WPSTOP_MAX_PAGE) + 1);
				}	
				DataConfig.save();				
				return count;
			}
			
			private void doHunt(int pageIndex) {
				String urlStr = WPSTOP_BASE + WPSTOP_TMPT.replaceFirst("index", pageIndex + "");
				InputStream in = null;
				try {
					in = new URL(urlStr).openStream();
					String content = IOUtil.readText(in);
					scanImage(content);
				} catch (Exception e) {
					LOGGER.error(e.getMessage(), e);
				} finally {
					try {
						in.close();
					} catch (Exception e) {
						LOGGER.error(e.getMessage(), e);
					}
				}
			}

			private void scanImage(String html) {
				Pattern previewWPPattern = Pattern.compile("/wallpapers/[^<>]*-[0-9]+x[0-9]+-[^<>]*\\.jpg", Pattern.CASE_INSENSITIVE);
				Matcher matcher = previewWPPattern.matcher(html);
				while(matcher.find()) {
					WPFileBean wpFileBean = new WPFileBean();
					InputStream pwpIn = null;
					InputStream wpIn = null;
					try {
						String previewPath = matcher.group();	
						if(DataConfig.isWPExistd(previewPath)) {
							continue;
						}
						putWPInfo(previewPath, wpFileBean);
						pwpIn = new URL(WPSTOP_BASE + previewPath).openStream();
						Integer[] size;
						for(int i = 0; i < WP_SIZES.length; i++) {
							size = WP_SIZES[i];
							String wpPath = changeSizeInPath(previewPath, size);					
							try {
								wpIn = new URL(WPSTOP_BASE + wpPath).openStream();
								wpFileBean.setWpURLPath(WPSTOP_BASE + wpPath);
								wpFileBean.setX(size[0]);
								wpFileBean.setY(size[1]);
								break;
							} catch (Exception e) {
								if(LOGGER.isDebugEnabled()) {
									LOGGER.debug(e.getMessage());
								}						
							} 
						}
						if(wpIn != null && pwpIn != null) {
							LOGGER.info("Downloading: "+ wpFileBean.getFileName());
							WPPConfig.savePreviewWPFile(wpFileBean.getFileName(), pwpIn);
							DataConfig.addWPFileBean(wpFileBean);
							count ++;
							updateProgress(count, MAX_WPP_DOWNLOAD);
						}
					} catch (Exception e) {
						LOGGER.error(e.getMessage(), e);
					} finally {
						try {
							if(pwpIn != null) { pwpIn.close(); }
							if(wpIn != null) { wpIn.close(); }
						} catch (Exception e) {
							//Don't care
						}
					}
				}
			}

			private String changeSizeInPath(String path, Integer[] size) {
				Pattern pattern = Pattern.compile("[0-9]+x[0-9]+");
				Matcher matcher = pattern.matcher(path);
				if(matcher.find()) {
					return matcher.replaceFirst(size[0] + "x" + size[1]);
				} else {
					throw new WPPException("Invalid path:" + path);
				}
			}
			
			private WPFileBean putWPInfo(String path, WPFileBean bean) {
				String title = "";
				for(String subName : path.replaceAll("-[0-9]+x[0-9]+.*jpg$", "")
						.replaceAll(".*/", "").split("-")) {
					title = title + subName.substring(0,1).toUpperCase() + subName.substring(1).toLowerCase() + " ";
				}
				bean.setTitle(title);
				String[] category = path.split("/");		
				bean.setCategory((String[]) ArrayUtils.subarray(category, 2, category.length - 1));
				bean.setCreateTimeStamp(new Date().getTime());
				bean.setFavore(0);
				bean.setFileName(WPFileBean.newFileName());	
				bean.setOrgUniqueName(path);
				return bean;
			}
		};
	}
}
